﻿using Tester.DL645.Core;

namespace Tester.DL645.Instructions
{
    /// <summary>
    /// 
    /// </summary>
    public abstract class AbstractInstruction
    {

        protected byte[] Address { get;  set; }

        protected byte ControlCode { get;  set; }


        /// <summary>
        /// 指令
        /// </summary>
        protected AbstractInstruction(string address, byte controlCode)
        {
            this.Address = Core.AddressField.Reverse(address).ToArray();
            this.ControlCode = controlCode;
             
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="buffer"></param>
        protected virtual void ApplyCheckCode(List<byte> buffer)
        {
            var crc = (byte)(buffer.Sum(x => x) % 256);
            buffer.Add(crc);
        }

        /// <summary>
        /// 包含 长度
        /// </summary>
        /// <param name="buffer"></param>
        protected abstract void ApplyData(List<byte> buffer);


        /// <summary>
        /// 编译
        /// </summary>
        public virtual AbstractInstruction  Build()
        {

            List<byte> buffer = new List<byte>();

            buffer.Add(Constants.FrameStartCharacter);

            buffer.AddRange(this.Address);

            buffer.Add(Constants.FrameStartCharacter);

            ///
             

            buffer.Add(this.ControlCode);
  
            this.ApplyData(buffer);
            
            this.ApplyCheckCode(buffer);
           
            buffer.Add(Constants.FrameEndCharacter);

            this.Bytes = buffer.ToArray();

            return this;

            
        }

        /// <summary>
        /// 获取 校验码
        /// </summary>
        /// <param name="bytes"></param>
        protected virtual byte GetCheckCode(List<byte> bytes)
        {
            var crc = (byte)(bytes.Sum(x => x) % 256);
            return crc;
        }

        /// <summary>
        /// 
        /// </summary>
        public  byte[] Bytes { get;  set; }
    }
}
